import type { Ref } from 'vue'
import type { DraggableOrderColumn } from '@/crud/use-columns'
import type { Size } from '@/types'
import { ArrowClockwise24Regular, ArrowMove24Regular, ArrowPrevious20Filled,
  CloudArrowDown24Regular, CloudArrowUp24Regular, FullScreenMaximize24Filled,
  FullScreenMinimize24Filled, TableResizeRow24Regular, TableSettings24Regular,
} from '@vicons/fluent'
import { NButton, NCheckbox, NDivider, NDropdown, NFlex, NIcon, NPopover, NSwitch, NTooltip } from 'naive-ui'
import { computed, defineComponent } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import { useOrderColumns } from '@/crud/use-columns'
import { useLocale } from '@/utils/locale'

interface Params {
  striped: Ref<boolean>
  size: Ref<Size>
  fullscreen: Ref<boolean>
  loading: Ref<boolean>
  showTooltips: Ref<boolean>
  emits: {
    (e: 'refresh'): void
    (e: 'import'): void
    (e: 'export'): void
  }
}
export function useToolbar({ striped, size, fullscreen, loading, showTooltips, emits }: Params) {
  const t = useLocale()

  const iconSize = computed(() => {
    return { small: 20, medium: 22, large: 24 }[size.value] || 22
  })

  const Divider = defineComponent({
    render() {
      return <NDivider vertical />
    },
  })

  const Striped = defineComponent({
    render() {
      return (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => t.value.tooltip.stripe,
            trigger: () => <NSwitch value={striped.value} onUpdate:value={e => striped.value = e} />,
          }}
        </NTooltip>
      )
    },
  })

  const Refresh = defineComponent({
    render() {
      return (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => t.value.tooltip.refresh,
            trigger: () => (
              <NButton
                text
                loading={loading.value}
                onClick={() => {
                  loading.value = true
                  emits('refresh')
                }}
              >
                {{
                  icon: () => (
                    <NIcon size={iconSize.value}>
                      <ArrowClockwise24Regular />
                    </NIcon>
                  ),
                }}
              </NButton>
            ),
          }}
        </NTooltip>
      )
    },
  })

  const Import = defineComponent({
    render() {
      return (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => t.value.tooltip.import,
            trigger: () => (
              <NButton text onClick={() => emits('import')}>
                <NIcon size={iconSize.value}>
                  <CloudArrowUp24Regular />
                </NIcon>
              </NButton>
            ),
          }}
        </NTooltip>
      )
    },
  })

  const Export = defineComponent({
    render() {
      return (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => t.value.tooltip.export,
            trigger: () => (
              <NButton text onClick={() => emits('export')}>
                <NIcon size={iconSize.value}>
                  <CloudArrowDown24Regular />
                </NIcon>
              </NButton>
            ),
          }}
        </NTooltip>
      )
    },
  })

  const Size = defineComponent({
    render() {
      return (
        <NDropdown
          onSelect={value => size.value = value}
          trigger="click"
          options={[
            { label: t.value.tooltip.small, key: 'small' },
            { label: t.value.tooltip.medium, key: 'medium' },
            { label: t.value.tooltip.large, key: 'large' },
          ]}
          value={size.value}
        >
          <NTooltip disabled={!showTooltips.value}>
            {{
              default: () => t.value.tooltip.size,
              trigger: () => (
                <NButton text>
                  <NIcon size={iconSize.value}>
                    <TableResizeRow24Regular />
                  </NIcon>
                </NButton>
              ),
            }}
          </NTooltip>
        </NDropdown>
      )
    },
  })

  const Fullscreen = defineComponent({
    render() {
      return (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => fullscreen.value
              ? t.value.tooltip.fullscreenMinimize
              : t.value.tooltip.fullscreenMaximize,
            trigger: () => (
              <NButton text onClick={() => fullscreen.value = !fullscreen.value}>
                <NIcon size={iconSize.value}>
                  {fullscreen.value ? <FullScreenMinimize24Filled /> : <FullScreenMaximize24Filled />}
                </NIcon>
              </NButton>
            ),
          }}
        </NTooltip>
      )
    },
  })

  const ColumnSetting = defineComponent({
    setup() {
      const columns = useOrderColumns()
      const updateColumns = (value: DraggableOrderColumn[] | null) => {
        columns.value = value
      }

      return () => (
        <NTooltip disabled={!showTooltips.value}>
          {{
            default: () => t.value.tooltip.columnSetting,
            trigger: () => (
              <NPopover
                trigger="click"
                placement="bottom-end"
                content-style="max-height: 50vh; overflow-y: auto"
              >
                {{
                  trigger: () => (
                    <NButton text>
                      <NIcon size={iconSize.value}>
                        <TableSettings24Regular />
                      </NIcon>
                    </NButton>
                  ),
                  header: () => (
                    <NFlex justify="space-between">
                      {t.value.tooltip.columnSetting}
                      <NButton text type="primary" onClick={() => updateColumns(null)}>
                        {t.value.tooltip.reset}
                      </NButton>
                    </NFlex>
                  ),
                  default: () => (
                    <VueDraggable
                      modelValue={columns.value || []}
                      handle=".draggable"
                      animation={150}
                      // eslint-disable-next-line ts/ban-ts-comment
                      // @ts-ignore
                      onUpdate:modelValue={updateColumns}
                    >
                      {columns.value?.map(column => (
                        <NFlex
                          align="center"
                          key={column.key}
                          style="margin-bottom: 8px;"
                        >
                          <NButton text class="draggable" style="cursor: move">
                            <NIcon size={iconSize.value}>
                              <ArrowMove24Regular />
                            </NIcon>
                          </NButton>

                          <NCheckbox
                            checked={column.visible}
                            onUpdate:checked={(checked) => {
                              column.visible = checked
                              updateColumns(columns.value)
                            }}
                          >
                            {typeof column.title === 'function' ? column.title() : column.title}
                          </NCheckbox>

                          <NFlex align="center" size="small" style="margin-left: auto;">
                            <NTooltip disabled={!showTooltips.value}>
                              {{
                                default: () => t.value.tooltip.fixed2left,
                                trigger: () => (
                                  <NButton
                                    text
                                    focusable={false}
                                    type={column.fixed === 'left' ? 'primary' : 'default'}
                                    onClick={() => {
                                      column.fixed = column.fixed === 'left' ? null : 'left'
                                      updateColumns(columns.value)
                                    }}
                                  >
                                    <NIcon size={iconSize.value}>
                                      <ArrowPrevious20Filled />
                                    </NIcon>
                                  </NButton>
                                ),
                              }}
                            </NTooltip>

                            <NDivider vertical />

                            <NTooltip disabled={!showTooltips.value}>
                              {{
                                default: () => t.value.tooltip.fixed2right,
                                trigger: () => (
                                  <NButton
                                    text
                                    focusable={false}
                                    type={column.fixed === 'right' ? 'primary' : 'default'}
                                    onClick={() => {
                                      column.fixed = column.fixed === 'right' ? null : 'right'
                                      updateColumns(columns.value)
                                    }}
                                  >
                                    <NIcon size={iconSize.value}>
                                      <ArrowPrevious20Filled style="transform: rotate(180deg);" />
                                    </NIcon>
                                  </NButton>
                                ),
                              }}
                            </NTooltip>
                          </NFlex>
                        </NFlex>
                      ))}
                    </VueDraggable>
                  ),
                }}
              </NPopover>
            ),
          }}
        </NTooltip>
      )
    },
  })

  return {
    iconSize,
    nodes: {
      Divider,
      Striped,
      Refresh,
      Import,
      Export,
      Size,
      Fullscreen,
      ColumnSetting,
    },
  }
}

export type UseToolbarReturn = ReturnType<typeof useToolbar>
